package cn.itcast.item.service.impl;

import cn.itcast.hmall.dto.common.PageDTO;
import cn.itcast.hmall.dto.common.ResultDTO;
import cn.itcast.hmall.dto.common.ThreadLocalUtil;
import cn.itcast.hmall.dto.item.RequestItem;
import cn.itcast.hmall.dto.item.SearchItemDTO;
import cn.itcast.hmall.pojo.item.Item;
import cn.itcast.item.constatnts.MqConstatnts;
import cn.itcast.item.mapper.ItemMapper;
import cn.itcast.item.service.ItemsService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author oldwine
 * @date 2022/6/20
 * @Version 1.0
 */
@Service
@Slf4j
public class ItemsServiceImpl extends ServiceImpl<ItemMapper, Item> implements ItemsService {

    @Autowired
    private ItemMapper itemMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 根据查询条件实现分页查询功能
     *
     * @param vo 查询条件
     * @return 返回分页查询结果
     */
    @Override
    public PageDTO<Item> queryByPage(SearchItemDTO vo) {
        //1.获取当前页码和每页显示条数
        int pageNum = vo.getPage();
        int pageSize = vo.getSize();

        //2.构建分页对象
        Page<Item> page = new Page<>((pageNum - 1) * pageSize, pageSize);

        if (Strings.isNullOrEmpty(vo.getName())
                && Strings.isNullOrEmpty(vo.getBrand())
                && Strings.isNullOrEmpty(vo.getCategory())) {
            itemMapper.selectPage(page, null);
            List<Item> items = page.getRecords();
            long total = page.getTotal();
            PageDTO<Item> pageDTO = new PageDTO<>();
            pageDTO.setTotal(total);
            pageDTO.setList(items);
            return pageDTO;
        } else {

            //3.构建条件对象
            LambdaQueryWrapper<Item> wrapper = Wrappers.lambdaQuery(Item.class);
            wrapper.like(Item::getName, vo.getName())
                    .eq(Item::getBrand, vo.getBrand())
                    .eq(Item::getCategory, vo.getCategory())
                    .ge(Item::getCreateTime, vo.getBeginDate())
                    .le(Item::getUpdateTime, vo.getEndDate());

            //4.根据条件查询数据
            itemMapper.selectPage(page, wrapper);
            long total = page.getTotal(); //总条数
            List<Item> itemsPage = page.getRecords();
            PageDTO<Item> pageDTO = new PageDTO<>();
            pageDTO.setTotal(total);
            pageDTO.setList(itemsPage);
            //5.封装数据
            return pageDTO;
        }
    }

    /**
     * 根据id查询商品
     *
     * @param id 商品id
     * @return 返回商品对象
     */
    @Override
    public Item quetyByItemId(Long id) {
        Item item = itemMapper.selectById(id);
        return item;
    }

    /**
     * 添加商品信息
     *
     * @param item 封装前端请求对象
     */
    @Override
    public ResultDTO insertItem(RequestItem item) {
        try {
            // 1.将前端接收的数据封装到Item对象中
            Date date = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String format = sdf.format(date);
            Date creatTime = sdf.parse(format);
            Item build = Item.builder()
                    .name(item.getName())
                    .category(item.getCategory())
                    .brand(item.getBrand())
                    .price(Long.valueOf(item.getPrice()))
                    .stock(Integer.valueOf(item.getStock()))
                    .spec(item.getSpec())
                    .image(item.getImage())
                    .isAD(item.getIsAD())
                    .createTime(creatTime)
                    .updateTime(creatTime)
                    .status(2)  //添加商品时,默认设置未下架状态
                    .build();
            //2.调用insert方法插入数据库
            int insert = itemMapper.insert(build);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return ResultDTO.ok();
    }

    /**
     * 根据id修改商品状态
     *
     * @param id     商品id
     * @param status 商品状态信息
     * @return 结果
     */
    @Override
    public ResultDTO updateById(Long id, Integer status) {
        Item item = itemMapper.selectById(id);
        item.setStatus(status);
        int count = itemMapper.updateById(item);
        //TODO:向消息队列中发送消息
        //如果status ==1 代表商品上架 发送消息至上架队列 status ==2 下架,发送至下架队列
        if (status == 1) {
            rabbitTemplate.convertAndSend(MqConstatnts.ITEM_EXCHANGE, MqConstatnts.ITEM_INSERT_KEY, id);
        }

        if (status == 2) {
            rabbitTemplate.convertAndSend(MqConstatnts.ITEM_EXCHANGE, MqConstatnts.ITEM_DELETE_KEY, id);
        }
        return ResultDTO.ok(count);
    }

    /**
     * 修改商品信息
     *
     * @param vo 封装的请求参数
     * @return 返回结果
     */
    @Override
    public ResultDTO updateItem(Item vo) {

        Item item = itemMapper.selectById(vo.getId());
        item.setName(vo.getName());
        item.setCategory(vo.getCategory());
        item.setBrand(vo.getBrand());
        item.setPrice(Long.valueOf(vo.getPrice()));
        item.setStock(Integer.valueOf(vo.getStock()));
        item.setSpec(vo.getSpec());
        item.setImage(vo.getImage());
        item.setIsAD(vo.getIsAD());
        int count = itemMapper.updateById(item);
        ThreadLocalUtil.clear();
        return ResultDTO.ok(count);
    }

    /**
     * 根据商品id删除商品信息
     *
     * @param id 商品id
     * @return 结果
     */
    @Override
    public ResultDTO deleteItemById(Long id) {
        int count = itemMapper.deleteById(id);
        return ResultDTO.ok(count);
    }

    @Override
    public List<Item> queryByPage(int pageNum, int pageSize) {
        //2.构建分页对象
        Page<Item> page = new Page<>(pageNum, pageSize);

        itemMapper.selectPage(page, null);
        List<Item> items = page.getRecords();
        return items;

    }

    /**
     * 扣减库存方法
     *
     * @param id  商品id
     * @param num 数量
     */
    @Override
    public void subStock(Long id, Integer num) {
        Item item = itemMapper.selectById(id);
        Integer stock = item.getStock() - num;
        item.setStock(stock);

        //设置条件
        LambdaQueryWrapper<Item> wrapper = Wrappers.lambdaQuery(Item.class);
        wrapper.eq(Item::getId,id);
        int count = itemMapper.update(item, wrapper);
        log.info("库存扣除方法的影响行数:{}",count);

    }

    /**
     * 添加库存方法
     * @param id 商品id
     * @param num 数量
     */
    @Override
    public void addStock(Long id, Integer num) {
        Item item = itemMapper.selectById(id);
        Integer stock = item.getStock() + num;
        item.setStock(stock);

        //设置条件
        LambdaQueryWrapper<Item> wrapper = Wrappers.lambdaQuery(Item.class);
        wrapper.eq(Item::getId,id);
        int count = itemMapper.update(item, wrapper);
        log.info("库存添加方法的影响行数:{}",count);
    }
}
